package com.ns.core.utils.date;

import com.ns.core.utils.sg.ResultError;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * 日期工具类
 *
 * @author lw
 * @since 2024/09/27
 */
public class CalenderUtil {
    /**
     * 获取dateFormat对象
     *
     * @return DateFormat
     */
    private static DateFormat getDateFormat(String pattern) {
        if (StringUtils.hasText(pattern)) {
            return new SimpleDateFormat(pattern);
        }
        return new SimpleDateFormat();
    }


    /**
     * 获取calendar
     *
     * @return List
     */
    private static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 获取当前日期
     *
     * @return Date
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 获取当前日期字符串
     *
     * @param dateTime 日期
     * @param pattern  时间格式
     * @return String
     */
    public static String getDate2Str(String pattern, Date dateTime) {
        if (Objects.isNull(dateTime)) {
            dateTime = getDate();
        }
        return switch (pattern) {
            case CalendarPattern.ALL -> getDateFormat(CalendarPattern.ALL).format(dateTime);
            case CalendarPattern.ALL_ -> getDateFormat(CalendarPattern.ALL_).format(dateTime);
            case CalendarPattern.ALL_YMD_HMS -> getDateFormat(CalendarPattern.ALL_YMD_HMS).format(dateTime);
            case CalendarPattern.ALL_YH -> getDateFormat(CalendarPattern.ALL_YH).format(dateTime);
            case CalendarPattern.YMD_CN -> getDateFormat(CalendarPattern.YMD_CN).format(dateTime);
            case CalendarPattern.YMD -> getDateFormat(CalendarPattern.YMD).format(dateTime);
            case CalendarPattern.Y_M_D -> getDateFormat(CalendarPattern.Y_M_D).format(dateTime);
            case CalendarPattern.H_M_S -> getDateFormat(CalendarPattern.H_M_S).format(dateTime);
            case CalendarPattern.SSS -> getDateFormat(CalendarPattern.SSS).format(dateTime);
            default -> getDateFormat(pattern).format(dateTime);
        };
    }

    /**
     * 获取当前日期字符串
     *
     * @param dt      日期字符串
     * @param pattern 时间格式
     * @return date
     */
    public static Date getStrToDate(String pattern, String dt) {
        try {
            return getDateFormat(pattern).parse(dt);
        } catch (ParseException e) {
            throw new ResultError("日期转换出现异常！");
        }
    }

    /**
     * 获取时间戳
     *
     * @param dt      日期字符串
     * @param pattern 时间格式
     * @return Long
     */
    public static Long getTimeStamp(String pattern, String dt) {
        return getStrToDate(pattern, dt).getTime();
    }

    /**
     * 偏移方法
     *
     * @param pattern pattern
     * @param dateStr 日期
     * @param type    偏移类型
     * @param num     偏移量
     * @return Date
     */
    public static Date offset(String pattern, String dateStr, Integer type, Integer num) {
        Date date = getStrToDate(pattern, dateStr);
        Calendar calendar = getCalendar(date);
        switch (type) {
            case Calendar.YEAR -> {
                int year = calendar.get(Calendar.YEAR);
                calendar.set(Calendar.YEAR, year + num);
            }
            case Calendar.MONTH -> {
                int month = calendar.get(Calendar.MONTH);
                calendar.set(Calendar.MONTH, month + num);
            }
            case Calendar.DAY_OF_YEAR -> {
                int day = calendar.get(Calendar.DAY_OF_YEAR);
                calendar.set(Calendar.DAY_OF_YEAR, day + num);
            }
            case Calendar.HOUR -> {
                int hour = calendar.get(Calendar.HOUR);
                calendar.set(Calendar.HOUR, hour + num);
            }
            case Calendar.MINUTE -> {
                int minute = calendar.get(Calendar.MONTH);
                calendar.set(Calendar.MINUTE, minute + num);
            }
            default -> calendar.set(Calendar.SECOND, num);
        }
        return calendar.getTime();
    }

    /**
     * 返回指定时间的YYYY-MM-dd hh:mm:ss 字符串格式
     */
    public static String getDtString(Date d) {
        return new SimpleDateFormat(CalendarPattern.ALL_YMD_HMS).format(d);
    }

    /**
     * 将一个字符串转换为日期格式（YYYY-MM-dd HH:mm:ss）
     */
    public static Date getDt(String d) {
        try {
            return new SimpleDateFormat(CalendarPattern.ALL_YMD_HMS).parse(d);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 返回当前时间的指定形式 如（YYYY_MM_dd_HH_mm_ss）
     *
     * @return String
     */
    public static String getNowString(String format) {
        return new SimpleDateFormat(format).format(new Date());
    }

    /**
     * 指定日期，指定格式
     *
     * @return String
     */
    public static String getDateString(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 获取指定日期的1号
     */
    public static Date getMonthStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 偏移方法
     *
     * @param pattern pattern
     * @param dateStr 日期
     * @param type    偏移类型
     * @param num     偏移量
     * @return String
     */

    public static String addStr(String pattern, String dateStr, int type, int num) {
        return getDate2Str(pattern, offset(pattern, dateStr, type, num));
    }


    /**
     * 根据时间戳获取指定格式的日期时间
     *
     * @param timestamp 时间戳
     * @return String
     */
    public static String getTimeStampToFormat(Long timestamp, String format) {
        if (ObjectUtils.isEmpty(timestamp)) {
            throw new ResultError("请选则有效时间！");
        }
        Date date = new Date(timestamp);
        return getDate2Str(format, date);
    }

}
